#pragma once
#include "TBinTreeNodeBase.h"
#include "TBinTreeNode.h"


enum TTraverseMode{PreOrder,InOrder,PostOrder,LevelOrder };

template <typename TElem>
class TBinTree
{
private:
	TBinTreeNodeBase<TElem> *root;
	long numNodes;
public:
	TBinTree(void);
	~TBinTree(void);

	virtual TBinTreeNodeBase<TElem> * GetRoot(){return root;}
	virtual void SetRoot(TBinTreeNodeBase<TElem> * rt){root=rt; }
	virtual long GetLevel(TBinTreeNodeBase<TElem> * pNode);
	virtual long GetHeight(TBinTreeNodeBase<TElem> * pNode);
	virtual long GetNumSubNodes(TBinTreeNodeBase<TElem> * pNode);
	virtual long GetNumSubNodes(void);
	virtual long GetNumLeaves(TBinTreeNodeBase<TElem> * pNode);
	virtual long Cluster(TBinTreeNodeBase<TElem> * pNode, TElem **e, TTraverseMode tm);
	virtual long Cluster(TBinTreeNodeBase<TElem> * pNode, TBinTreeNode<TElem> **pe,TTraverseMode tm);
	virtual long Cluster2(TBinTreeNodeBase<TElem> * pNode,TBinTreeNodeBase<TElem> **pe,TTraverseMode tm);
	virtual long ClusterDescendants(TBinTreeNodeBase<TElem> * pNode,TBinTreeNodeBase<TElem> **pe,TTraverseMode tm=PreOrder, int startLevel=1,int endlEvel=-1);
	virtual long ClusterAncestors(TBinTreeNodeBase<TElem> * pNode,TElem **e);
	virtual long ClusterAncestors(TElem &e,TBinTreeNodeBase<TElem> ** pNodes);
	virtual long ClusterJuniors(TBinTreeNodeBase<TElem> * pNode, TBinTreeNodeBase **pe,TTraverseMode travMode=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterSeniors(TBinTreeNodeBase<TElem> * pNode, TBinTreeNodeBase<TElem> **pe, TTraverseMode TravMode=PreOrder,int startLevel=1,int endLevel=-1);
	virtual TBinTreeNodeBase * DeleteSubTree(TBinTreeNodeBase<TElem> * pNode,char sonNo);
	
   /*
	virtual long ClusterDescendants(TBinTreeNodeBase<TElem> * pNode,TElem **es,TTraverseMode tm=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterDescendants(TElem &e,TBinTreeNodeBase<TElem> **pe,TTraverseMode tm=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterDescendants(TElem &e,TElem **es, TTraverseMode tm=PreOrder,int startLevel=1,int endLevel=-1);

	virtual long ClusterJuniors(TBinTreeNodeBase<TElem> * pNode,TElem **es,TTraverseMode travMode=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterJuniors(TElem &e,TBinTreeNodeBase<TElem> **pe, TTraverseMode travMode=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterJuniors(TElem &e,TElem **es,TTraverseMode travMode=PreOrder,int startLevel=1,int endLevel=-1);

	virtual long ClusterSeniors(TBinTreeNodeBase<TElem> * pNode, TElem **es,TTraVerseMode travMode=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterSeniors(TElem &e,TBinTreeNodeBase<TElem> **pe,TTraVerseMode travMode=PreOrder,int startLevel=1,int endLevel=-1);
	virtual long ClusterSeniors(TElem &e,TElem **es,TTraverseMode travMode=PreOrder,int startLevel=1 int endLevel=-1);

	virtual TBinTreeNodeBase<TElem> * Locate(TBinTreeNodeBase<TElem> * rt,TElem &e,TTraverseMode travMode=PreOrder,long sn=1);
	virtual TBinTreeNodeBase<TElem> * DeleteSubTree(TBinTreeNodeBase<TElem> * pNode,char sonNo);
	*/
	virtual long ReleaseSubs(TBinTreeNodeBase<TElem> * pNode);
	virtual TBinTreeNodeBase<TElem> * Locate(TBinTreeNodeBase<TElem> *rt,TElem *e);
	virtual TBinTreeNodeBase<TElem> * InPreToTree(TElem *pa,TElem *ia,long pl,long p2,long i1,long i2);
	virtual TBinTreeNodeBase<TElem> * GListToTree(long * gListExp,TElem *es,long numElem);
	virtual TBinTreeNodeBase<TElem> * PreOrderExToTree(TElem * nodes, int numElem);
	virtual TBinTreeNodeBase<TElem> * PreOrderExToTree(TElem * nodes);
	virtual long TreeToGList(TBinTreeNodeBase<TElem> *rt,TElem *e);
	virtual void Print(TBinTreeNodeBase<TElem> *rt,char mode);

};
